﻿using CloudStorageLight.Core;
using CloudStorageLight.Core.Web;
using CloudStorageLight.Web.Models;
using ElCamino.AspNet.Identity.AzureTable;
using ElCamino.AspNet.Identity.AzureTable.Model;
using Microsoft.InformationProtectionAndControl;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Storage.Table;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Claims;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.SessionState;
using System.Web.UI;

namespace CloudStorageLight.Web
{
    public class MvcApplication : BaseHttpApplication
    {
        public MvcApplication()
        {
            var wrapper = new EventHandlerTaskAsyncHelper(DoAsyncWork);
            this.AddOnAuthenticateRequestAsync(wrapper.BeginEventHandler, wrapper.EndEventHandler);
        }

        public static string GetMailAddress(ClaimsIdentity claimsIdentity)
        {
            try
            {
                var ret = (from c in claimsIdentity.Claims
                        where c.Type == Microsoft.IdentityModel.Claims.ClaimTypes.Email
                           select c.Value).FirstOrDefault();

                if (ret == null)
                {
                    ret = (from c in claimsIdentity.Claims
                           where c.Type == Microsoft.IdentityModel.Claims.ClaimTypes.Upn
                           select c.Value).FirstOrDefault();

                }
                return ret;
            }
            catch
            {
                if (HttpContext.Current != null && HttpContext.Current.User.Identity.IsAuthenticated)
                {
                    return HttpContext.Current.User.Identity.Name;
                }
                return null;
            }
        }

        protected virtual void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            if (this.User != null && this.User.Identity.IsAuthenticated)
            {
                if (this.User.Identity.AuthenticationType != "ApplicationCookie")
                {
                    var name = User.Identity.Name;
                    if (name == null) name = GetMailAddress((ClaimsIdentity)this.User.Identity);
                    if (name != null)
                    {
                        var identity = new GenericIdentity(name);
                        var account = BlobService.GetCurrentCloudAccount();
                        if (account != null)
                        {
                            if (account.GetAdministrators().Contains(name))
                            {
                                identity.AddClaim(new Claim("AdminAuthenticate", "true"));
                            }
                            identity.AddClaim(new Claim("CloudAccount", account.AccountName));
                        }
                        var pricinpal = new GenericPrincipal(identity, new string[] { });
                        HttpContext.Current.User = pricinpal;
                    }
                    //else
                    //{
                    //    HttpContext.Current.User = null;
                    //}
                }
            }

        }

        protected void Application_Start()
        {

            if (SystemSettings.Instance.UseRMS)
            {
                try
                {
                    RmsUtil.Init(); //ERROR FREE
                }
                catch { }
            }

            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            GlobalConfiguration.Configuration.EnsureInitialized();

            ShortTermJob();
            MiddleTermJob();

            if (SystemSettings.Instance.FullTextServerRole) 
            {
                FullTextServerRoleJob();
                CrawlJob();
            }

            Trace.Listeners.Add(new HttpContextTraceListener());
        }

        protected override void Application_OnEndRequest(Object sender, EventArgs e)
        {
            base.Application_OnEndRequest(sender, e);

            HttpApplication app = (HttpApplication)sender;
            // 認証が成功していない場合は「WWW-Authenticate」ヘッダを付加する
            if (app.Response.StatusCode == 401)
            {
                BasicAuthenticateUtil.AddUnauthorizedHeader(app);
            }

        }

        protected void Application_PostAuthorizeRequest()
        {
            HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.Required);
        }

        private async Task DoAsyncWork(object sender, EventArgs e)
        {
            var app = (HttpApplication)sender;
            var ctx = app.Context;
            await BasicAuthenticateUtil.Authenticate(app);

        }
    }
}
